home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 140
/
Gekkan Dennou Club - 2000.1 Vol. 140 (Japan).7z
/
Gekkan Dennou Club - 2000.1 Vol. 140 (Japan) (Track 1).bin
/
tools
/
dshell
/
dsh333bs.lzh
/
dtool.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-09-28
|
12KB
|
658 lines
/*
dshell v3
ユーティリティなど
*/
#include "dsh.h"
static void w_wait2_sub(int);
static void w_wait2_prt(int);
static void ASK_Window_Close(void);
/*
*--------------------------------------
* 仮想マウスの状態チェック
*--------------------------------------
*/
void
dmsstat(int *ax, int *ay, int *abl, int *abr)
{
int dbl = 0, dbr = 0;
/*
* とりあえず初期化
*/
*abl = 0;
*abr = 0;
/*
* ここは、ジョイスティックのボタンを読み取る
* ジョイスティックのボタン読み込みは、ジョイカードでの使用を想定しています。
* よって上下スクロールの時のボタン左右がマウスと逆の場合があります。
*/
if (Jflg) {
switch (strig(1)) {
case 1:
*abl = 0;
*abr = -1;
break;
case 2:
*abl = -1;
*abr = 0;
break;
case 3:
*abl = -1;
*abr = -1;
break;
}
}
if (Kflg) {
/*
* キーボードのROLL UP/ROLL DOWNを読む
* 最初はXF1/XF2でしたけど、カーソルキーに近いこともあり
* 片手で操作しやすいのでU/Dにかえました
*/
switch (BITSNS(0x07)) {
case 0x01:
*abl = -1;
*abr = 0;
break; /* R_up */
case 0x02:
*abl = 0;
*abr = -1;
break; /* R_down */
case 0x03:
*abl = -1;
*abr = -1;
break; /* u+d */
}
/*
* やっぱりXF1/XF2でも操作(上下スクロール・復帰)出来るようにしました
*/
switch (BITSNS(0x0A)) {
case 0x20:
*abl = -1;
*abr = 0;
break; /* XF1 */
case 0x40:
*abl = 0;
*abr = -1;
break; /* XF2 */
case 0x60:
*abl = -1;
*abr = -1;
break; /* X1+X2 */
}
/*
* ESCで復帰出来るようにする
*/
if (esc_on()) {
*abl = -1;
*abr = -1;
}
/*
* リターンキーで決定出来るようにする
*/
if (cr_on() || enter_on()) {
*abl = -1;
*abr = 0;
}
}
/*
* マウスのボタン読み取り
*/
msstat(ax, ay, &dbl, &dbr);
if (dbl || dbr) {
*abl = dbl;
*abr = dbr;
}
}
/*
*------------------------------------------------------
* 仮想マウスでのマウスカーソルの位置を調べる
*------------------------------------------------------
*/
void
dmspos(int *mx, int *my)
{
int ax = 0, ay = 0;
int dest = 0;
/*
* カーソルの移動速度の決定
*/
if (Jflg || Kflg) {
dest = NOMAL_SPEED + (CSpdUp * 2); /* カーソルの速度標準 */
if (opt1_on() || shift_on()) {
dest = HIGH_SPEED + (CSpdUp * 2); /* 速度3倍 */
}
}
/*
* ここは、ジョイスティックのレバーを読み取る
*/
if (Jflg) {
switch (stick(1)) {
case 1:
ax = -dest;
ay = dest;
break;
case 2:
ay = dest;
break;
case 3:
ax = dest;
ay = dest;
break;
case 4:
ax = -dest;
break;
case 5:
break;
case 6:
ax = dest;
break;
case 7:
ax = -dest;
ay = -dest;
break;
case 8:
ay = -dest;
break;
case 9:
ax = dest;
ay = -dest;
break;
}
}
/*
* ここは、テンキーを読み取る
* というのがあったのですが、死ぬほど遅く動き(カーソル)もがたがたなので
* とっぱらいました。
*/
/*
* カーソルキーの読み取り
*/
if (Kflg) {
switch (BITSNS(7)) {
case 0x08:
ax = -dest;
break; /* ← */
case 0x10:
ay = -dest;
break; /* ↑ */
case 0x20:
ax = dest;
break; /* → */
case 0x40:
ay = dest;
break; /* ↓ */
case 0x18:
ax = -dest;
ay = -dest;
break; /* ←↑ */
case 0x30:
ax = dest;
ay = -dest;
break; /* ↑→ */
case 0x48:
ax = -dest;
ay = dest;
break; /* ←↓ */
case 0x60:
ax = dest;
ay = dest;
break; /* ↓→ */
}
}
/*
* 仮想マウスの本体
*/
mspos(mx, my); /* 本来のマウスカーソルの座標 */
if (ax || ay) {
/*
ジョイスティックやキーボードの入力があれば
本来のマウスカーソルの位置に、下駄をはかせて
マウスカーソルを再表示する。
*/
ax += *mx;
ay += *my;
if (ax < 0)
ax = 0;
if (ay < 0)
ay = 0;
setmspos(*mx = ax, *my = ay);
}
}
/* ジョイスティック=マウスの使用モード(フラグ)ON/OFF切り替え */
void
JoyMouseSwitch()
{
Jflg = !Jflg;
}
/* キーボード=マウスの使用モード(フラグ)ON/OFF切り替え */
void
KeyMouseSwitch()
{
Kflg = !Kflg;
}
/* キーボード・ジョイスティックマウスのカーソルの基準速度切り替え */
void
CSpdUpSwitch()
{
CSpdUp = !CSpdUp;
}
/*
起動時、ジョイスティックから信号が来ているか
チェックする (JoystickMouse On だと画面が勝手に
スクロールするなどの症状が出るため)
*/
void
check_joystick()
{
if (!Jflg) {
return;
}
if (JOYGET(0) != 0xff) {
B_PRINT("ジョイスティック1の状態を確認して下さい\n(SPACEキー:ジョイスティックを使わないモードで起動)\r\n");
while ((char)JOYGET(0) != (char)0xff) {
if (KFLUSHIO(0xff) == ' ') {
Jflg = FALSE;
break;
}
}
}
}
/*
画面の真ん中にウィンドウを表示して、キーボードより
文字列を得る(メッセージ付)
find、fileload用…。
*/
int
getstr(struct INPPTR *inp, char *message, int inp_len)
{
int win_sx, win_sy, win_lx, win_ly, inp_sx, inp_sy, retval;
win_sx = ((CWIDTH - (inp_len + 4)) / 2) & -2;
win_sy = 10;
win_lx = inp_len + 4;
win_ly = 5;
inp_sx = win_sx + 2;
inp_sy = win_sy + 3;
/*
! キーバッファをクリアしてからウィンドウを開く
*/
KFLUSHIO(0xff);
tbox_w2(win_sx, win_sy, win_sx + win_lx, win_sy + win_ly); /* 外枠 */
tbox_w2(inp_sx, inp_sy, inp_sx + inp_len, inp_sy + 1); /* 入力枠 */
if (!(GMODE)) {
/*
! 変換ウィンドウのバックが見やすいように
! メニューバー下を消す
*/
fill(0, 496, GWIDTH - 1, 511, 2);
B_LOCATE(0, 31);
B_ERA_AL();
}
B_LOCATE(win_sx + 2, win_sy + 1);
B_COLOR(3);
B_PRINT(message);
B_CONSOL(inp_sx << 3, inp_sy << 4, inp_len + 3 - 1, 1 - 1);
OS_CURON();
/*
! 文字入力
*/
inp->max = inp_len;
retval = GETSS(inp); /* 入力:retval==入力文字数 */
ASK_Window_Close(); /* 日本語ウィンドウを消す */
Init_Under_Bar(); /* メニューバー下を復活する */
OS_CUROF();
/*
! 画面の復帰
*/
B_CONSOL(0, 0, 128 - 1, 64 - 1);
{
int i;
for (i = win_sy - 2; i <= win_sy + win_ly; i++) {
p_lin(lp + i, i);
}
}
return (retval);
}
/*
マウスボタンが離されるのを待つ
*/
void
wait_mb_off()
{
int x, y, l, r;
do {
dmsstat(&x, &y, &l, &r);
dmspos(&x, &y);
p_time(0);
} while (l || r);
}
/*
チャイルドプロセスから帰る時、
クリックをうながすメッセージを出す
*/
void
w_wait2()
{
int dx, dy, bl, br;
OS_CUROF();
KFLUSHIO(-1);
do {
dmsstat(&dx, &dy, &bl, &br);
} while (bl || br);
#define NO_WAIT_CLICK \
(debugMode && ((B_SFTSNS() & (LED_CODEIN | LED_ROMA | LED_KANA)) > LED_CODEIN))
if (NO_WAIT_CLICK)
return;
w_wait2_sub(1);
do {
dmsstat(&dx, &dy, &bl, &br);
if (space_on() || NO_WAIT_CLICK) {
bl = TRUE;
KFLUSHIO(-1);
}
if (dx || dy || !bl && !br && kbhit() || stick(1)) {
w_wait2_sub(1);
while (kbhit()) {
INPOUT(0xff);
}
} else {
w_wait2_sub(0);
}
} while (!bl && !br);
do {
dmsstat(&dx, &dy, &bl, &br);
} while (bl || br);
B_PRINT("\r\r");
}
static void
w_wait2_sub(int initf)
{
static int et, dspf, count;
if (initf) {
dspf = 1;
count = 14; /* 明滅回数(1明or1滅毎にcount down) */
et = init_et(120); /* 最初の1.2秒は普通に表示 */
w_wait2_prt(dspf);
return;
}
if (et > d_ontime()) {
return;
}
if (count < 0) {
return;
}
et = init_et(7); /* 約0.07秒ごと明滅 */
count--;
dspf = 1 - dspf;
w_wait2_prt(dspf);
return;
}
static void
w_wait2_prt(int display_f)
{
if (display_f) {
B_COLOR(5);
B_PRINT("\rマウスを『クリック』するとシェルに戻ります\r");
B_COLOR(3);
} else {
B_ERA_AL(); /* 行末まで消去 */
}
}
/*
ONTIME()+wait(1/100sec) 分の時間を返す
*/
asm("
_init_et::
moveq.l #$7f,d0 *ONTIME
trap #15
add.l 4(sp),d0
cmpi.l #24*60*60*100,d0
bcs @f
subi.l #24*60*60*100,d0
addq.w #1,d1
bra @f
_d_ontime:: *上位バイトに 0~127 の日情報を入れて返す ONTIME()
moveq.l #$7f,d0 *ONTIME
trap #15
@@: move.l d0,-(sp)
andi.b #$7f,d1
move.b d1,(sp)
move.l (sp)+,d0
rts
");
/*
日本語変換ウィンドウを閉じる
*/
static void
ASK_Window_Close(void)
{
asm("
pea 0.w
move.l #1,-(sp)
dc.w $FF22 *FPコール番号1番(knjctrl)
addq.l #8,sp");
}
/*
そのドライブ(drv:'A'~'Z')が
準備OKだったらTRUE、準備できてなかったらFALSEを返す
*/
int
drvready(char drv)
{
drv = toupper(drv);
if (drv >= 'A' && drv <= 'Z') {
return (DRVCTRL(0, drv - '@') & 0x04) ? FALSE : TRUE;
} else {
return FALSE;
}
}
/*
テキストマルチプレーン同時アクセスをセットしちまう
CRTCじかいじり
使った後はさっさと元に戻すこと
pl:テキストプレーン 0~3 のうち使用したいビットを立てて渡す
ただし 0 の時はマルチプレーンアクセスをやめる
0 か 3 以外を渡されると画面がヘンになるかもしれない…
v3.30
pl < 0 なら IOCS の文字描画色に対応するプレーンを採用
pl = 0 ならシステム既定値にリセット
CRTC R21 の他のビットは保存しない
*/
void
tcolor(char pl)
{
if (pl == 0) {
B_WPOKE(CRTCR21, 0x0033);
} else {
if (pl < 0)
curColor = pl = B_COLOR(-1) & 0x03;
pl &= 0x0f;
B_WPOKE(CRTCR21, (pl << 4) | 0x0100);
}
}
/*
Human68k標準の文字属性変更エスケープシーケンスかどうかチェックする
入力:文字列の0x1bの次位置を指すポインタ
戻値:エスケープシーケンス部分の長さ(0x1b除く)、エスケープシーケンスでなかった場合0
v3.30:
ESC[~m 以外に ESC[~C, ESC[~D (カーソル桁位置相対移動) も通す
*/
uchar escNumBuff[7 + 1];
int
isEscSeq(const uchar *p)
{
static const char escNum[] = {
// 0 1 2 3 4 5 6 7 8 9
0x03, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, // 0
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 10
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 20
0x40, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x00, // 30
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x00, // 40
};
uchar c, cc, *q;
const uchar *startp = p;
if (*p++ != '[')
return 0;
q = escNumBuff;
cc = curColor;
for (;;) {
c = *p++;
switch (c) {
case ' ':
case '\t':
case '\r':
continue;
case ';':
case 'm':
*q = '\0';
if (q > escNumBuff) {
int j;
signed char f;
j = atoi(q = escNumBuff);
if (j < 50) {
f = escNum[j];
if (f < 0)
cc ^= (f & 0x0f);
else if (f != 0)
cc = (f & 0x0f);
}
} else
cc = 0x03;
if (c == ';')
continue;
curColor = cc;
return p - startp;
case 'C':
case 'D':
case 'e':
case 'x':
*q = '\0';
return p - startp;
default:
if (c <= '9' && c >= '0') {
*q++ = c;
if (q - escNumBuff >= 7) { // IOCS の文字表示ルーチンは数字列の頭 7 文字しか見ない
while ((c = *p++) <= '9' && c >= '0'
|| c == ' ' || c == '\t' || c == '\r')
;
p--;
}
continue;
}
*q = '\0';
return 0;
}
}
}
/*
簡略版 filelength();
*/
long
dfilelength(int fno)
{
long n, curPos;
curPos = SEEK(fno, 0, SEEK_CUR);
if (curPos < 0)
return -1;
n = SEEK(fno, 0, SEEK_END);
SEEK(fno, curPos, SEEK_SET);
return n;
}
/*
環境変数を定義し、親~全祖先プロセスに継承
*/
void
setenv_and_export(const uchar *name, const uchar *value)
{
unsigned long *psp;
#if 0
本来、自身がフォアグラウンドで動作していることを確認する必要がある
(そうでないと、親プロセスが先に死んでいる可能性がある)が、省略
#endif
for (psp = ((unsigned long *)_PSP) - 4; psp != NULL; psp = (unsigned long *)B_LPEEK(psp + 1)) {
uchar *env = (uchar *)B_LPEEK(psp + 4);
if ((int)env > 0)
SETENV(name, env, value);
}
}